package com.touchstone.cloudpacs.service.impl;

import cn.hutool.core.util.NumberUtil;
import com.touchstone.cloudpacs.common.exception.BusinessException;
import com.touchstone.cloudpacs.common.utils.CommonUtils;
import com.touchstone.cloudpacs.respone.ServerParams;
import com.touchstone.cloudpacs.service.IHardwareParamService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HWDiskStore;
import oshi.hardware.NetworkIF;

import javax.annotation.Resource;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description :硬件参数查询接口
 * @Author :djw
 * @Date :16:22 2020/2/17
 */
@Slf4j
@Service("hardwareParamService")
public class HardwareParamServiceImpl implements IHardwareParamService {

    private SystemInfo systemInfo=new SystemInfo();

    @Override
    public Map getServerParams() {
        Map<String,Object> resMap=new HashMap<>(6);
        resMap.put("cpu",getCpu());
        resMap.put("ram",getMemory());
        resMap.put("network",getNetwork());
        resMap.put("disk",getDisk());
        return resMap;
    }
    /**
     * 获取内存参数
     *
     * @return com.touchstone.cloudpacs.respone.HardwareParam
     * @author djw
     * @date 2020/2/17 20:29
     */
    public ServerParams.Ram getMemory() {
        GlobalMemory memory = systemInfo.getHardware().getMemory();
        long total = memory.getTotal();
        long available = memory.getAvailable();
        long used = total - available;
        double usedRate = NumberUtil.div(used, total, 2);
        ServerParams.Ram resRam = new ServerParams.Ram(used, total, usedRate);
        log.info("内存使用情况：【{}】", resRam);
        return resRam;
    }

    /**
     * 获取磁盘参数
     *
     * @return com.touchstone.cloudpacs.respone.HardwareParam
     * @author djw
     * @date 2020/2/17 21:04
     */
    private ServerParams.Disk getDisk() {
        boolean isWindows = "WINDOWS".equals(SystemInfo.getCurrentPlatformEnum().toString());
        if (!isWindows) {
            log.warn("服务器系统不是windows,跳转到linux查询接口");
            return null;
        }
        HWDiskStore[] diskStores = systemInfo.getHardware().getDiskStores();
        if (CommonUtils.isEmpty(diskStores)) {
            throw new BusinessException("磁盘读取异常");
        }
        long total = 0;
        long used = 0;
        long readSpeed = 0;
        long writeSpeed = 0;
        if (diskStores.length > 0) {
            for (HWDiskStore diskStore : diskStores) {
                long size = diskStore.getSize();
                long writeBytes = diskStore.getWriteBytes();
                long reads = diskStore.getReads();
                long writes = diskStore.getWrites();
                total += size;
                used += writeBytes;
                readSpeed += reads;
                writeSpeed += writes;
            }
        }
        ServerParams.Disk resDisk = new ServerParams.Disk(used, total, readSpeed, writeSpeed);
        log.info("磁盘的具体使用情况：【{}】", resDisk);
        return resDisk;
    }

    /**
     * 获取CPU参数
     *
     * @return com.touchstone.cloudpacs.respone.HardwareParam
     * @author djw
     * @date 2020/2/17 21:04
     */
    private ServerParams.Cpu getCpu() {
        CentralProcessor processor = systemInfo.getHardware().getProcessor();
        double cpuUtilization = processor.getSystemCpuLoadBetweenTicks();
        int threadCount = systemInfo.getOperatingSystem().getThreadCount();
        int processCount = systemInfo.getOperatingSystem().getProcessCount();
        ServerParams.Cpu resCpu = new ServerParams.Cpu(processCount, threadCount, cpuUtilization);
        log.info("cpu使用情况：【{}】", resCpu);
        return resCpu;
    }

    /**
     * 获取网络参数
     *
     * @return com.touchstone.cloudpacs.respone.ServerParams.Network
     * @author djw
     * @date 2020/2/26 14:54
     */
    private ServerParams.Network getNetwork() {
        NetworkIF[] networkIFs = systemInfo.getHardware().getNetworkIFs();
        ServerParams.Network network = new ServerParams.Network();
        for (NetworkIF networkIF : networkIFs) {
            if (CommonUtils.isNotEmpty(networkIF.getIPv4addr()) && CommonUtils.isNotEmpty(networkIF.getIPv6addr())) {
                //网络接口的速度，以每秒bit数为单位。需要实时更新
                networkIF.updateNetworkStats();
                String iPv4addr = networkIF.getIPv4addr()[0];
                String iPv6addr = networkIF.getIPv6addr()[0];
                long receive = networkIF.getBytesRecv();
                long send = networkIF.getBytesSent();
                network.setIpv4(iPv4addr);
                network.setIpv6(iPv6addr);
                network.setReceive(receive);
                network.setSend(send);
            }
        }
        log.info("网络使用情况：【{}】", network);
        return network;
    }

    /**
     * 获取linux 磁盘使用率
     *
     * @return 磁盘使用率
     */
    private  double getUnixDiskUsage() {
        String ioCmdStr = "df -h /";
        String resultInfo = runCommand(ioCmdStr);
        String[] data = resultInfo.split(" +");
        double total = Double.parseDouble(data[10].replace("%", ""));
        return total / 100;
    }

    /**
     * 执行系统命令
     *
     * @param cmd 命令
     * @return 字符串结果
     */

    private String runCommand(String cmd) {
        StringBuilder info = new StringBuilder();
        try {
            Process pos = Runtime.getRuntime().exec(cmd);
            pos.waitFor();
            InputStreamReader isr = new InputStreamReader(pos.getInputStream());
            LineNumberReader lnr = new LineNumberReader(isr);
            String line;
            while ((line = lnr.readLine()) != null) {
                info.append(line).append("\n");
            }
        } catch (Exception e) {
            info = new StringBuilder(e.toString());
        }
        return info.toString();
    }

}
